package com.imc.griebeler.isomorphism;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;

/**
 * Algorithm borrowed from https://github.com/hirodev/isomorphic-words
 * No license was provided.
 * 
 * Basically it boils down to finding one way isomorphism for two words. If
 * after you flop the parameters, it's still isomorphic, then you're good to go.
 * 
 * @author griebeler
 *
 */
public class Main {
	public static void main(String[] args) {
		// String first = args[0];
		// String second = args[2];

		String first = "isomorphic";
		String second = "economizes";

		if (isIsomorphic(first, second)) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}

	private static boolean isIsomorphic(String first, String second) {
		if (first.length() != second.length()) {
			return false;
		}
		return isOneWayIsomorphic(first, second) && isOneWayIsomorphic(second, first);
	}

	/**
	 * Iterate through the first parameter to create a mapping to the second
	 * parameter.
	 * 
	 * If you find a character mapping being used twice, it's not isomorphic.
	 * 
	 * @param one
	 * @param two
	 * @return
	 */
	private static boolean isOneWayIsomorphic(String one, String two) {
		Character[] oneArray = ArrayUtils.toObject(one.toCharArray());
		Character[] twoArray = ArrayUtils.toObject(two.toCharArray());

		Map<Character, Character> usedCharacters = new HashMap<Character, Character>(one.length());

		for (int k = 0; k < oneArray.length; k++) {
			Character oneCharacter = oneArray[k];
			Character twoCharacter = twoArray[k];
			Character c = usedCharacters.get(oneCharacter);

			if (null != c && !c.equals(twoCharacter))
				return false;
			usedCharacters.put(oneCharacter, twoCharacter);
		}
		return true;
	}
}
